using System;
using System.Collections.Generic;
using System.Linq;
using DataStore.Domain;
using NHibernate;
using NHibernate.Linq;

namespace DataStore.Repositories
{
    /// <summary>
    /// Cover repository
    /// </summary>
    public class CoverRepository : IRepository<Cover>
    {
        readonly UnitOfWork _unitOfWork;

        
        /// <summary>
        /// Initializes a new instance of the <see cref="CoverRepository"/> class.
        /// </summary>
        /// <param name="unitOfWork">The unit of work.</param>
        public CoverRepository(UnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public Cover Get(object id)
        {
            throw new NotImplementedException();
        }

        public void Delete(Cover entity)
        {
            ISession session = _unitOfWork.Session;
            session.Delete(entity);
        }

        public void DeleteAll()
        {
            throw new NotImplementedException();
        }

        public void Save(Cover entity)
        {
            ISession session = _unitOfWork.Session;
            session.Save(entity);
        }

        public Cover SaveOrUpdate(Cover entity)
        {
            ISession session = _unitOfWork.Session;
            session.SaveOrUpdate(entity);
            return entity;
        }

        /// <summary>
        /// Updates the specified cover.
        /// </summary>
        /// <param name="cover">The cover.</param>
        public void Update(Cover cover)
        {
            ISession session = _unitOfWork.Session;
            session.Update(cover);
            
        }

        

        /// <summary>
        /// Gets all the covers.
        /// </summary>
        /// <value>All the covers.</value>
        public IEnumerable<Cover> All
        {
            get
            {
                ISession session = _unitOfWork.Session;
                return session.Linq<Cover>().ToList();
                
            }
        }

        public bool Exists(Cover entity)
        {
            throw new NotImplementedException();
        }

        public bool IsEmpty
        {
            get { throw new NotImplementedException(); }
        }

        public int Count(Cover entity)
        {
            throw new NotImplementedException();
        }

        public int CountAll()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Gets the default cover.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="cover">The cover to be set as default.</param>
        /// <returns></returns>
        public Cover GetDefault(CatalogItem item, Cover cover)
        {

            ISession session = _unitOfWork.Session;
                // Default && belong to catalgue item && type of cover (front or back)
                return (from def in session.Linq<Cover>()
                        where
                            def.IsDefault
                            && item.Cover.Contains(def)
                            && def.Type == cover.Type
                        select def)
                        .FirstOrDefault();
            
            
        }

        /// <summary>
        /// Sets the cover as default.
        /// </summary>
        /// <param name="item">The item the cover belongs to.</param>
        /// <param name="cover">The cover.</param>
        public void SetAsDefault(CatalogItem item, Cover cover)
        {
            ISession session = _unitOfWork.Session;
            
            // Set others to not default
            // Default && belong to catalgue item && type of cover (front or back)
            var defaultCovers = from def in session.Linq<Cover>()
                                where 
                                    def.IsDefault 
                                    && item.Cover.Contains(def)
                                    && def.Type == cover.Type
                                select def;
            foreach (var defaultCover in defaultCovers)
            {
                defaultCover.IsDefault = false;
                session.Update(defaultCover);
            }
            
            // Set current cover to default
            cover.IsDefault = true;
            session.Update(cover);

            
            
        }
    }
}